package com.mall.order.biz.handler;

import com.alibaba.fastjson.JSON;
import com.mall.commons.tool.exception.BizException;
import com.mall.order.biz.context.AbsTransHandlerContext;
import com.mall.order.biz.context.CreateOrderContext;
import com.mall.order.biz.context.TransHandlerContext;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.dal.entitys.Stock;
import com.mall.order.dal.persistence.OrderItemMapper;
import com.mall.order.dal.persistence.StockMapper;
import com.mall.order.dto.CartProductDto;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.redisson.client.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description: 扣减库存处理器
 * @Author： wz
 * @Date: 2019-09-16 00:03
 **/
@Component
@Slf4j
public class SubStockHandler extends AbstractTransHandler {

    @Autowired
    private StockMapper stockMapper;

    @Autowired
	RedissonClient redissonClient;

	@Override
	public boolean isAsync() {
		return false;
	}

	/*
	 * @description: 扣减库存
	 * @return: boolean
	 * @author: mabinbin
	 * @date: 2021/8/25
	 */
	@Override
	@Transactional
	public boolean handle(TransHandlerContext context) {

		//向下转型
		CreateOrderContext createOrderContext = (CreateOrderContext) context;

		//获得购物车中商品的list
		List<CartProductDto> productList = createOrderContext.getCartProductDtoList();

		//封装商品id的list
		List<Long> productIds = createOrderContext.getBuyProductIds();
		if (CollectionUtils.isEmpty(productIds)) {
			productIds = productList.stream().map(u -> u.getProductId()).collect(Collectors.toList());
		}
		//将productIds按数字大小排序
		productIds.sort((o1, o2) -> (int) (o1 - o2));

		//通过productIds查询stock的list，并且锁定库存（for update）
		List<Stock> stockList = stockMapper.findStocksForUpdate(productIds);

		//商品已经加入购物车，说明有库存
		if (CollectionUtils.isEmpty(stockList)) {
			StringBuffer stringBuffer = new StringBuffer();
			for (CartProductDto productDto : productList) {
				stringBuffer.append(productDto.getProductName() + "、");
			}
			String string = stringBuffer.toString();
			String substring = string.substring(0, string.length() - 1);
			throw new BizException(OrderRetCode.SYSTEM_TIMEOUT.getCode(),substring + "的商品库存未初始化");
		}

		//部分库存不存在
		if (stockList.size() != productIds.size()) {
			//获得以存在的库存中的商品id
			List<Long> stockItemIds = new ArrayList<>();
			for (Stock stock : stockList) {
				stockItemIds.add(stock.getItemId());
			}

			StringBuffer stringBuffer = new StringBuffer();
			//如果id不被包含就加入到字符串
			for (CartProductDto productDto : productList) {
				if (stockItemIds.contains(productDto.getProductId())) {
					continue;
				}
				stringBuffer.append(productDto.getProductName() + "、");
			}
			String string = stringBuffer.toString();
			String substring = string.substring(0, string.length() - 1);
			throw new BizException(OrderRetCode.SYSTEM_TIMEOUT.getCode(),substring + "的商品库存未初始化");
		}

		List<CartProductDto> available = new ArrayList<>();
		//部分商品库存不足，循环判断商品的量不足
		long currentTime = System.currentTimeMillis();
		for (CartProductDto productDto : productList) {
			for (Stock stock : stockList) {
				if (productDto.getProductId().equals(stock.getItemId()) &&
						productDto.getProductNum() > stock.getStockCount()) {

					//第一次进入
					RBucket<String> lastClick = redissonClient.getBucket("lastClick");
					String last = lastClick.get();
					if (last == null) {
						lastClick.set(String.valueOf(currentTime));
						throw new BizException(OrderRetCode.SYSTEM_TIMEOUT.getCode(),
								productDto.getProductName() + "的商品库存仅剩" + stock.getStockCount() + "件,5秒之内再次点击，将下单有库存商品");
					}

					//第二次进入，如果点击间隔超过5秒
					long lastTime = Long.parseLong(last);
					Long df = currentTime - lastTime;
					if (df > 5000) {
						lastClick.set(String.valueOf(currentTime));
						throw new BizException(OrderRetCode.SYSTEM_TIMEOUT.getCode(),
								productDto.getProductName() + "的商品库存仅剩" + stock.getStockCount() + "件,5秒之内再次点击，将下单有库存商品");
					}

					continue;

				} else if (productDto.getProductId().equals(stock.getItemId())) {
					//如果不包含这个商品就加入到list中
					if (!available.contains(productDto)) {
						available.add(productDto);
					}
				}
			}
		}

		//如果available为null直接抛出当前
		if (CollectionUtils.isEmpty(available)) {
			throw new BizException(OrderRetCode.SYSTEM_TIMEOUT.getCode(), "当前购物车中的商品库存均不足，请重新调整购买数量");
		}

		//重新计算将要下单的总金额
		BigDecimal totalPay = new BigDecimal(0);
		//对下单的商品扣减库存stock_count --> lock_count
		for (CartProductDto productDto : available) {
			Long productId = productDto.getProductId();
			Long productNum = productDto.getProductNum();

			//商品购买的数量超过最高限购库存
			Stock targetStock = stockMapper.selectByPrimaryKey(productId);
			Integer restrictCount = targetStock.getRestrictCount();
			if (productNum > restrictCount) {
				throw new BizException(OrderRetCode.SYSTEM_TIMEOUT.getCode(),productDto.getProductName() + " 每单限购" + restrictCount + "件");
			}

			//通过商品id更新stock表
			Stock stock = new Stock();
			stock.setItemId(productId);
			//已有lockCount加上现在的lockCount
			stock.setLockCount(productNum.intValue());
			//已有的StockCount减去productNum
			stock.setStockCount(-productNum);

			//更新库存
			stockMapper.updateStock(stock);
			totalPay = totalPay.add(productDto.getSalePrice().multiply(new BigDecimal(productDto.getProductNum())));
		}

		//修改需要插入数据库的商品和总价格
		createOrderContext.setCartProductDtoList(available);
		createOrderContext.setOrderTotal(totalPay);
		//释放available中的所有商品
		available = null;

		return true;
	}
}